﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Hangjing.Model;
using Hangjing.SQLServerDAL;
using Hangjing.Common;
using System.Security.Cryptography.X509Certificates;
using System.Xml;

namespace Hangjing.Weixin
{
    /// <summary>
    /// 微信支付退款
    /// </summary>
    public class WeChat_Refund
    {
        public static string charset = "UTF-8";
        public string orderid;
        protected HttpContext context;

        public WeChat_Refund(string _orderid, HttpContext context)
        {
            this.context = context;
            orderid = _orderid;
        }

        /// <summary>
        /// 提交退款
        /// </summary>
        /// <returns></returns>
        public apiResultInfo submitRefund()
        {
            string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";

            TimeSpan toNow = DateTime.Now.AddHours(12).Subtract(new DateTime(1970, 1, 1));
            string deliver_timestamp = toNow.TotalSeconds.ToString("#0");

            CustorderInfo order = new Custorder().GetModel(orderid);



            WeiXinAccountInfo config = new WeiXinAccount().GetModelByCityID(order.cityid);
            if (config == null)
            {
                config = CacheHelper.GetWeiXinAccount(); ;
            }

            apiResultInfo rs = new apiResultInfo();

            PayOrderLogInfo paylog = new PayOrderLog().GetList(1, 1, "OrderId='" + order.orderid + "' and  state = 2", "DataId", 1).FirstOrDefault();
            if (paylog == null)
            {
                rs.state = 0;
                rs.msg = "此订单未支付";
                return rs;
            }

            //设置支付参数
            RequestHandler delivernotifyReqHandler = new RequestHandler(context);
            delivernotifyReqHandler.setParameter("appid", config.AppId);
            delivernotifyReqHandler.setParameter("mch_id", config.partnerid);
            delivernotifyReqHandler.setParameter("nonce_str", getNoncestr());
            delivernotifyReqHandler.setParameter("out_trade_no", paylog.Batch);
            delivernotifyReqHandler.setParameter("out_refund_no", "" + paylog.Batch + "r");
            delivernotifyReqHandler.setParameter("total_fee", (order.paymoney * 100).ToString("0"));
            delivernotifyReqHandler.setParameter("refund_fee", (order.paymoney * 100).ToString("0"));
            delivernotifyReqHandler.setParameter("op_user_id", config.partnerid);

            delivernotifyReqHandler.setKey(config.apikey);


            string app_signature = delivernotifyReqHandler.createMd5Sign();

            //退款接口post数据
            string postdata = delivernotifyReqHandler.parseRefunXML();

            Hangjing.Weixin.HttpHelper objhttp = new Hangjing.Weixin.HttpHelper();
            objhttp.isToLower = false;
            Hangjing.Weixin.HttpItem objHttpItem = new Hangjing.Weixin.HttpItem()
            {
                URL = url,
                Encoding = "utf-8",
                Method = "POST",
                CerPath = @"c:\www\cert\apiclient_cert.p12",
                Cer_PWD = config.partnerid,
                UserAgent = context.Request.UserAgent,
                Postdata = postdata.ToString(),
            };

            // X509Certificate2 certificate = new X509Certificate2(objHttpItem.CerPath, objHttpItem.Cer_PWD, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);


            string ResultMsg = objhttp.GetHtml(objHttpItem);

            Hangjing.AppLog.AppLog.Info("退款：" + ResultMsg + "\r\n postdata=" + postdata);

            System.Xml.XmlDocument d = new System.Xml.XmlDocument();
            d.LoadXml(ResultMsg);
            System.Xml.XmlCDataSection n = d.SelectSingleNode("/xml/return_code").FirstChild as System.Xml.XmlCDataSection;
            System.Xml.XmlCDataSection result_code = d.SelectSingleNode("/xml/result_code").FirstChild as System.Xml.XmlCDataSection;


            if (n != null && n.Value == "SUCCESS" && result_code != null && result_code.Value == "SUCCESS")
            {
                rs.state = 1;
                rs.msg = "退款申请已经提交";
            }
            else
            {

                System.Xml.XmlCDataSection err_code_des = d.SelectSingleNode("/xml/err_code_des").FirstChild as System.Xml.XmlCDataSection;
                if (err_code_des != null && err_code_des.Value != null)
                {
                    rs.state = 0;
                    rs.msg = err_code_des.Value;
                }
                else
                {
                    rs.state = 0;
                    rs.msg = "退款失败:";
                }
                    
            }

          

            return rs;
        }

        /// <summary>
        /// 查询退款
        /// </summary>
        /// <returns></returns>
        public WeChat_RefundLogInfo queryRefund()
        {
            WeChat_RefundLogInfo info = new WeChat_RefundLogInfo();
            info.payorderid = "";

            string url = "https://api.mch.weixin.qq.com/pay/refundquery";

            CustorderInfo order = new Custorder().GetModel(orderid);

            WeiXinAccountInfo config = new WeiXinAccount().GetModelByCityID(order.cityid);
            if (config == null)
            {
                config = CacheHelper.GetWeiXinAccount(); ;
            }


            apiResultInfo rs = new apiResultInfo();

            PayOrderLogInfo paylog = new PayOrderLog().GetList(1, 1, "OrderId='" + order.orderid + "' and  state = 2", "DataId", 1).FirstOrDefault();
            if (paylog == null)
            {          
                return info;
            }

            //设置支付参数
            RequestHandler delivernotifyReqHandler = new RequestHandler(context);
            delivernotifyReqHandler.setParameter("appid", config.AppId);
            delivernotifyReqHandler.setParameter("mch_id", config.partnerid);
            delivernotifyReqHandler.setParameter("nonce_str", getNoncestr());
            delivernotifyReqHandler.setParameter("out_trade_no", paylog.Batch);

            delivernotifyReqHandler.setKey(config.apikey);


            string app_signature = delivernotifyReqHandler.createMd5Sign();

            //退款接口post数据
            string postdata = delivernotifyReqHandler.parseRefunXML();

            Hangjing.Weixin.HttpHelper objhttp = new Hangjing.Weixin.HttpHelper();
            objhttp.isToLower = false;
            Hangjing.Weixin.HttpItem objHttpItem = new Hangjing.Weixin.HttpItem()
            {
                URL = url,
                Encoding = "utf-8",
                Method = "POST",
                UserAgent = context.Request.UserAgent,
                Postdata = postdata.ToString(),
            };

            string ResultMsg = objhttp.GetHtml(objHttpItem);

            Hangjing.AppLog.AppLog.Info("查询退款：" + ResultMsg + "\r\n postdata=" + postdata);

            System.Xml.XmlDocument d = new System.Xml.XmlDocument();
            d.LoadXml(ResultMsg);
            System.Xml.XmlCDataSection n = d.SelectSingleNode("/xml/return_code").FirstChild as System.Xml.XmlCDataSection;
            System.Xml.XmlCDataSection result_code = d.SelectSingleNode("/xml/result_code").FirstChild as System.Xml.XmlCDataSection;


            if (n != null && n.Value == "SUCCESS" && result_code != null && result_code.Value == "SUCCESS")
            {
                
                XmlNode refund_fee_0_node = d.SelectSingleNode("/xml/refund_fee").FirstChild as System.Xml.XmlNode; ;

                info.payorderid = (d.SelectSingleNode("/xml/out_trade_no").FirstChild as System.Xml.XmlCDataSection).Value;
                info.payorderid = info.payorderid.Substring(0, info.payorderid.Length - 3);

                info.refund_fee = Convert.ToDecimal(refund_fee_0_node.Value) / 100;
                info.refund_recv_accout = (d.SelectSingleNode("/xml/refund_recv_accout_0").FirstChild as System.Xml.XmlCDataSection).Value;
                info.total_fee = 0;
                info.addtime = DateTime.Now;
                info.revevar1 = (d.SelectSingleNode("/xml/refund_status_0").FirstChild as System.Xml.XmlCDataSection).Value;
                info.revevar2 = "";
                info.revevar3 = "";


            }

            return info;
        }


        /// <summary>
        /// 生成随机串
        /// </summary>
        /// <returns></returns>
        public static string getNoncestr()
        {
            Random random = new Random();
            return Utils.GetMD5(random.Next(1000).ToString(), charset);
        }

        /// <summary>
        /// 时间戳
        /// </summary>
        /// <returns></returns>
        public static string getTimestamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }
    }
}
